/**
* \mainpage Estocastico
*
*
*
* \section intro_sec Introducao
*
*   O Estocastico mede a capacidade das forcas compradoras de realizar o fechamento proximo ao\n
*   valor maximo atingido dentro de um determinado intervalo de tempo e a capacidade\n
*   das forcas vendedoras em trazer esse fechamento para as proximidades do valor\n
*   minimo da janela de tempo.
*
*
* \section hist_sec Historico
* O estocastico eh um importante indicador do tipo oscilador criado por George Lane.
*
*
* @header      estocastico.h
* @version     1.0
* @date        17/10/2010
* @author      Rafael Tosta Santos <rafa.ecomp@gmail.com> \n
* @group       UEFS - Engenharia da Computacao
* @see         Projeto Anual I - Prof. Angelo Duarte\n Candelabro
* @link        Repositorio <http://candelabro.googlecode.com/svn/trunk/candelabro>
* @ref         Candelabro::estocastico
*
*/


#include "estocastico.h"
#include <iostream>
#include <fstream>


/** Construtor vazio*/
Estocastico::Estocastico()
{
}

/** Calcula o Estocastico
 * Esse calculo eh realizado da seguinte forma:
 * 1 - Calcula os valores do grafico %K
 * 2 - Com os valores de %K eh calculado os valores de %D
 *
 * @param <double> fechamento[] vetor com todos os fechamentos da acao a ser calculado
 * @param <int> numDias quantidades de dias presente no fechamento
 * @param <double> maximo[] vetor com todos os valores maximos da acao a ser calculado
 * @param <double> minimo[] vetor com todos os valores minimos da acao a ser calculado
 * @param <int> periodo quantidade de dias em que se basear para realizar os calculos
 */
void Estocastico::CalculaEstocastico(double *fechamento,int numDias, double *maximo, double *minimo, int periodo){
    this->numDias = numDias;
    this->periodo = periodo;

    //calculo da linha %k
  int tam1 = this->numDias - this->periodo;
   double *l_k = new double [tam1];
      for(int i = 0; i < tam1; i++){
          l_k[i] = this->Calcula_K(fechamento,maximo,minimo)[i];

      }

      //calculo da linha %D
      int tam2 = this->numDias - 2*this->periodo + 1;
      double *l_d = new double [tam2];
         for(int i = 0; i < tam2; i++){
             l_d[i] = this->Calcula_D(l_k)[i];
         }

         // atribuindo os valores as variaveis do objeto
         this->linhaK = l_k;
         this->linhaD = l_d;


}


/** Calcula os valores %K
 * Esse calculo eh realizado da seguinte forma:
 * 1- Eh definido uma faixa de valores dos vetores maximo e minimo
 * 2- Realizado a seguinte expressao:
 *   K = ((fechamento[aual] - valorMin)/(valorMax - valorMin))*100.0;
 *   onde valorMin e valorMax sao os que foram definidos no primeiro passo
 * 3 - Repetindos os passos 1 e 2 ate que os valores dos vetores cheguem ao fim
 *
 * @param <double> fechamento[] vetor com todos os fechamentos da acao a ser calculado
 * @param <double> maximo[] vetor com todos os valores maximos da acao a ser calculado
 * @param <double> minimo[] vetor com todos os valores minimos da acao a ser calculado
*/
double *Estocastico::Calcula_K(double *fechamento,double *maximo, double *minimo){
    int size = this->numDias - this->periodo;

    double K[size];
    double min[this->periodo];
    double max[this->periodo];
    double tempMin = 0;


    //definindo uma faixa de valores dos vetores maximo e minimo
    for(int i = 0; i< size; i++){
        for(int o = 0; o< this->periodo; o++){
            max[o] = maximo[i + o];
            min[o] = minimo[i + o];
        }

        tempMin = this->Minimo(min);
        K[i] = ((fechamento[i] - tempMin)/(this->Maximo(max) - tempMin))*100.0;



    }

    return  K;
}


/** Calcula os valores %D
 * Esse calculo eh realizado da seguinte forma:
 * 1 - Eh definido uma faixa de valores do vetor linha_k
 * 2 - Realiza uma media movel simples com esses valores
 * 3 - Repetindos os passos 1 e 2 ate o final dos valores do vetor linha_k
 *
 * @param <double> linha_k[] vetor com todos pontos do grafico %k
*/
double *Estocastico::Calcula_D(double *linha_k){
    int tam = this->numDias - 2*this->periodo + 1;
    double D[tam];

    double m ;



    for(int i = 0; i < tam; i++){

         m = 0 ;
        for(int o = 0; o < this->periodo; o++){
            m = m + linha_k[i + o];

        }

        D[i] =  m/this->periodo;

    }

    return D;

}


/** Retorna o valor maximo do periodo
 *
 *
 * @param <double> high[] vetor com valores maximos da acao em um determinado periodo
 * @return <double> valorMax valor maximo do vetor high
*/
double Estocastico::Maximo(double *high){
    double max = high[0];
    for (int i=1; i<this->periodo; i++){
        if (high[i] > max){
            max = high[i];
        }
    }
    return max;
}


/** Retorna o valor minimo do periodo
 *
 *
 * @param <double> low[] vetor com valores minimos da acao em um determinado periodo
 * @return <double> valorMin valor minimo do vetor low
*/
double Estocastico::Minimo(double *low){
    double min = low[0];
    for (int i=1; i<this->periodo; i++){
        if (low[i] < min){
            min = low[i];
        }
    }
    return min;
}

/** Retorna os valores de %k
 *
 * @return <double> linhaK[] vetor com os pontos do grafico %K
*/
double* Estocastico::getValoresK(){
    return this->linhaK;
}

/** Retorna os valores de %D
 *
 * @return <double> linhaD[] vetor com os pontos do grafico %D
*/
double* Estocastico::getValoresD(){
    return this->linhaD;
}

